package com.agv.core.lectorDeGlobalizadoresImpl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.apache.log4j.Logger;

import com.agv.core.lectorDeGlobalizador.ILectorTxt;

//esta clase obtiene los datos segun reglas de identificacion
//la obtencion de los registros para este tipo de archivo, en lo que se refere a multiples pasajeros y pagos mixtos es como sigue
//lo primero que hay que tomar en cuenta es que no puede haber un caso en el que ocurran ambos hechos,
//es decir, un archivo solo puede contener un pasajero con pago mixto o bien varios pasajeros con pago simple
//como en el caso de los archivos PNR se incluira un indice que anteceda al los elementos que pertenescan 
//a los campos repetidos
//con la diferencia que solo variara uno de los dos

public class LectorTxt implements ILectorTxt {

	ArrayList<String> list;

	/** Componente de logeo para la clase */
	private static final Logger log = Logger.getLogger(Rutas.class); 

	public ArrayList<HashMap<String, String>> txt(ArrayList<String> list)
	throws Exception{
		HashMap<String, String> data = new HashMap<String, String>();
		this.list = list;
		Numero numero = new Numero();
		FormatoDeFechas fechas = new FormatoDeFechas();
		Rutas rutas = new Rutas();
		
		int c1 = traerNumeroLinea("C-");
		int d1 = traerNumeroLinea("D-");
		int mu1 = traerNumeroLinea("MU");
		int air1 = traerNumeroLinea("AIR");
		int k1 = traerNumeroLinea("K-");
		int tax1 = traerNumeroLinea("TAX-");
		int fm1 = traerNumeroLinea("FM");
		int fp1 = traerNumeroLinea("FP");
		int a1 = traerNumeroLinea("A-");
		int fo1 = traerNumeroLinea("FO");
		int h1 = traerNumeroLinea("H-");
		
		String origen;
		String destino;
		StringBuilder vuelo = new StringBuilder();

		int mixto = list.get(fp1).indexOf("+");

		ArrayList<Integer> pasajero = new ArrayList<Integer>();
		ArrayList<Integer> ticket = new ArrayList<Integer>();
		ArrayList<Integer> remark = new ArrayList<Integer>();
		ArrayList<Integer> viaje = new ArrayList<Integer>();
		ArrayList<String> rutaViaje = new ArrayList<String>();
		ArrayList<String> ruta = new ArrayList<String>();

		ArrayList<HashMap<String, String>> dataList = new ArrayList<HashMap<String, String>>();
		
		// aqui se obtienen todos los datos que necesitan ser iterados
		for (int i = 0; i < list.size(); i++) {
			if (list.get(i).startsWith("H-")) {
				// aqui se llena la lista VIAJE con la posicion de todos los
				// elementos
				// correspondientes a datos de vuelo
				viaje.add(i);
				// esta parte se encarga de obtener las cd de origen y destino
				// para formar la ruta
				String[] h;
				h = list.get(i).split(";");

				origen = h[1].substring(h[1].length()-3, h[1].length());
				destino = h[3];

				rutaViaje.add(origen);
				rutaViaje.add(destino);
//				aqui se obtienen los numeros de vuelo y se concatenan
				vuelo.append(h[5].substring(6,11)+"|");
				
				
			}
		}
		
		if(vuelo.length()>0){
			vuelo.deleteCharAt(vuelo.length()-1);
		}
//		RUTA recibe la ruta ya formateada
		ruta = rutas.rutas(rutaViaje);

		for (int i = 0; i < list.size(); i++) {
			if (list.get(i).startsWith("I-")) {
				pasajero.add(i);
			}
		}

		for (int i = 0; i < list.size(); i++) {
			if (list.get(i).startsWith("T-")) {
				ticket.add(i);
			}
		}

		for (int i = 0; i < list.size(); i++) {
			if (list.get(i).startsWith("RM*CS:")) {
				remark.add(i);
			}
		}

		data.put("NB_RESERVA", list.get(mu1).substring(6, 12));

		String[] c;
		c = list.get(c1).split("-");
		data.put("AGENTE_EMITE_PNR", c[1].substring(c[1].indexOf("/") + 2));
		data.put("AGENTE_RESERVA_PNR", c[2]);

		String[] d;
		d = list.get(d1).split(";");
		data.put("FH_RESERVA", fechas.numeroFecha(d[0].substring(2, d[0]
				.length())));
		data.put("FH_EMISION", fechas.numeroFecha(d[1]));

		String[] mu;

		mu = list.get(mu1).split(";");
		data.put("SEUDO", mu[6]);
		data.put("CD_IATA", mu[7]);

		String[] air;
		air = list.get(air1).split(";");
		data.put("NU_CLIENTE", air[0].substring(air[0].length() - 6, air[0]
				.length()));

		String[] k;
		k = list.get(k1).split(";");
		data.put("MONEDA", k[0].substring(3, 6));

		String[] tax;
		tax = list.get(tax1).split(";");
		data.put("CD_TUA", tax[1].substring(tax[1].length() - 3));
		data.put("CD_IVA", tax[0].substring(tax[0].length() - 3));
		data.put("CD_TUA2", tax[2].substring(tax[2].length() - 3));

		data.put("TARIFA_BASE", k[0].substring(6, 17));

		data.put("TUA", numero.esNumero(tax[1]
				.substring(0, tax[1].indexOf(" "))));

		if (tax[0].indexOf("MX", tax[0].indexOf(" ")) > 0
				|| tax[0].indexOf("XO", tax[0].indexOf(" ")) > 0) {
			data.put("IVA", tax[0].substring(tax[0].length() - 12, tax[0]
					.length() - 3));
		} else {
			data.put("IVA", "0");

			Integer tua = Integer.parseInt(data.get("TUA"));
			String iva = tax[0].substring(tax[0].length() - 12,
					tax[0].length() - 3);
			float impuesto = Float.parseFloat(iva.trim());
			tua += impuesto;
			data.put("TUA", tua.toString());
		}
		data.put("TUA_2", numero.esNumero(tax[2].substring(0, tax[2]
				.indexOf(" "))));

		data.put("TOTAL", numero.esNumero(k[12].trim()));

		String[] fm;
		fm = list.get(fm1).split("\\*");
		data.put("PORCENTAJE_COMISION", fm[2].substring(0, 1));

		double total = Double.parseDouble(data.get("TOTAL"));
		double porcentaje = Double.parseDouble(data.get("PORCENTAJE_COMISION"));
		Double importe = total * porcentaje / 100;
		importe = numero.decimales(importe);
		data.put("IMPORTE_COMISION", importe.toString());

		data.put("TIPO_COMISION", fm[1].substring(0, 1));

		String[] a;
		a = list.get(a1).split(";");
		data.put("CD_AEROLINEA", a[1].substring(0, a[1].indexOf(" ")));

		if (data.get("MONEDA").equals("MXN")) {
			data.put("INCADOR_RUTA", "D");
		} else {
			data.put("INCADOR_RUTA", "MXN");
		}

		// aqui se leera el archivo correspondiente a la ruta

		String[] h;
		h = list.get(h1).split(";");
		
		String[] fecha;
		fecha = list.get(viaje.get(viaje.size()-1)).split(";");

		data.put("CD_PRODUCTO", "1");
		data.put("FH_SALIDA", fechas.anioReserva(h[5].substring(15, 20)));
		data.put("FH_LLEGADA", fechas.anioEmision(data.get("FH_SALIDA"), fecha[5].substring(30, 35)));
		data.put("HORA_LLEGADA", fechas.hora(fecha[5].substring(25, 28)));
		data.put("HORA_SALIDA", fechas.hora(h[5].substring(20, 24)));
		data.put("CD_CD_ORG", h[1].substring(h[1].length() - 3, h[1].length()));
		data.put("NB_CD_ORIGEN", h[2]);
		data.put("CD_CD_DESTINO", h[3]);
		data.put("NB_CD_DESTINO", h[4]);
		data.put("NU_VUELO", vuelo.toString());
		data.put("CLASE_SERVICIO", h[5].substring(11, 13));
		data.put("TIEMPO_VUELO", h[16]);
		data.put("INDICADOR_SERVICIO", "");
		data.put("BANDERA_CAMBIO", "");
		data.put("CD_PARADA", h[1].substring(3, 4));
		data.put("ID_TERMINAL_SALIDA", "");
		data.put("PUERTA_SALIDA", "");
		data.put("ID_TERMINAL_ENTRADA", "");
		data.put("PUERTA_LLEGADA", "");
		data.put("NU_ASIENTO", "");
		data.put("CD_PRODUCTOSEC", "");
		data.put("NU_CONF", "");
		data.put("ESTATUS", h[6].substring(1, 3));
		data.put("NU_ARTICULO", "");
		data.put("CANTIDAD", "1");
		data.put("TASA_LOCAL", "");
		data.put("MONEDA_LOCAL", "");
		data.put("DIRECCION", "");
		data.put("REF_TELEFONICA", "");
		data.put("PESO_EQUIPAJE", "");
		data.put("CD_TARIFA_BASE", "");
		data.put("CD_EXP_TARBASE", "");
		data.put("MILLAS", h[18]);
		data.put("CONEXION", "");
		data.put("CANCELADO", "");

		// aqui se obtienen los datos por boleto
		for (Integer l = 0; l < pasajero.size(); l++) {

			HashMap<String, String> mapa = new HashMap<String, String>();

			String[] i;
			i = list.get(pasajero.get(l)).split(";");

			if (i[3].indexOf("-") > 0 && i[3].lastIndexOf("-")!=i[3].indexOf("-")) {
				mapa.put("NB_CLIENTE", i[3].substring(i[3].indexOf("-") + 2,
						i[3].indexOf("-", i[3].indexOf("-") + 1) - 2));
			} else {
				mapa.put("NB_CLIENTE", "");
			}
			mapa.put("NU_PASAJERO", i[1].substring(0, 2));
			mapa.put("NB_PASAJERO", i[1].substring(i[1].indexOf("/") + 1));

			if (fo1 > 0) {
				mapa.put("BOLETO_ORIGINAL", list.get(fo1).substring(6, 16));
			} else {
				mapa.put("BOLETO_ORIGINAL", "");
			}

			String[] fp;
			fp = list.get(fp1).split("/");
			if (list.get(fp1).indexOf("O/") > 0) {
				// falta la especificacion
				mapa.put("TIPO_PAGO", "");

				if (mapa.get("TIPO_PAGO").equals("CC")) {
					mapa.put("FORMA_PAGO", "");
					mapa.put("NU_TARJETA_CREDITO", "");
				} else {
					mapa.put("FORMA_PAGO", "");
					mapa.put("NU_TARJETA_CREDITO", "");
				}
			} else {

				if (mixto > 0 && list.get(fp1).indexOf("+/") < 0) {
					mapa.put("PAGO_MIXTO", "SI");
					mapa.put("TIPO_PAGO_1", "CC");
					mapa.put("TIPO_PAGO_2", "CA");

					int mas = fp[0].indexOf("+");
					mapa.put("FORMA_PAGO", fp[0].substring(mas + 1, mas + 3));

					mapa.put("NU_TARJETA_CREDITO", numero.esNumero(fp[0]));
				} else {
					mapa.put("PAGO_MIXTO", "NO");
					mapa.put("TIPO_PAGO", fp[0].substring(2, 4));

					if (mapa.get("TIPO_PAGO").equals("CC")) {
						mapa.put("FORMA_PAGO", fp[0].substring(4, 6));
						mapa.put("NU_TARJETA_CREDITO", numero.esNumero(fp[0]));
					} else {
						mapa.put("FORMA_PAGO", "");
						mapa.put("NU_TARJETA_CREDITO", "");
					}
				}
				if (remark.size() > 0)
					mapa.put("REMARK_23", list.get(remark.get(l)).substring(
							list.get(remark.get(l)).indexOf(":") + 1,
							list.get(remark.get(l)).lastIndexOf("*")));

			}

			String[] t;
			t = list.get(ticket.get(l)).split("-");

			int largo = t[2].length();
			// BASEBOLETO toma los primeros digitos, la base del boleto, que no
			// cambia
			String baseBoleto;
			// NUMBOLETO obtiene el numero del primer boleto
			Integer numBoleto;
			// RANGO es donde obtiene la cantidad de boletos
			Integer rango = 0;

			baseBoleto = t[2].substring(0, largo - 2);
			numBoleto = Integer.parseInt(t[2].substring(8, largo));
			if (t.length == 4) {
				rango = Integer.parseInt(t[3]) - numBoleto;
			}
//			contador para obtener la ruta segun el boleto
			int contador = 0;
			// en este for se incorporan los boletos sucesivos de acuerdo al
			// rango
			for (int j = numBoleto; j < numBoleto + rango + 1; j++) {
				HashMap<String, String> bConjuntos = new HashMap<String, String>();
				String boleto;
				if (j > 9) {
					boleto = baseBoleto + j;
				} else {
					boleto = baseBoleto + "0" + j;
				}

				// si largo es cero entonces no hay boletos en conjunto
				if (rango == 0) {

					bConjuntos.put("NU_BOLETO", boleto);
					bConjuntos.put("BOLETO_CONJUNTO", "");
					
				} else {
					bConjuntos.put("NU_BOLETO", boleto.toString());
					if (j == numBoleto) {
						bConjuntos.put("BOLETO_CONJUNTO", "");
					} else {
						int conjunto = j - 1;
						bConjuntos
								.put("BOLETO_CONJUNTO", baseBoleto + conjunto);
					}
					
				}
				bConjuntos.put("RUTA", ruta.get(contador));
				
				mapa.putAll(data);
				bConjuntos.putAll(mapa);
				dataList.add(bConjuntos);
			}
		}

		for (int i = 0; i < dataList.size(); i++) {
			Iterator ite = dataList.get(i).entrySet().iterator();
			while (ite.hasNext()) {
				Map.Entry elem = (Map.Entry) ite.next();
				log.debug("mapa " + elem.getKey() + "\t\t\t "
						+ elem.getValue());
			}
		}

		return dataList;
	}

	public int traerNumeroLinea(String prefijo) {

		int linea = 0;

		Iterator<String> it = list.iterator();
		while (it.hasNext()) {

			if (it.next().toString().startsWith(prefijo)) {
				break;
			}
			linea++;
		}
		if (linea == list.size())
			return -1;

		return linea;

	}

	public ArrayList<HashMap<String, String>> leer(ArrayList<String> list) throws Exception{

		if (list.contains("CANCELADO")) {
			return cancelar(list);
		} else {
			return txt(list);
		}
	}

	private ArrayList<HashMap<String, String>> cancelar(ArrayList<String> list2) {

		ArrayList<HashMap<String, String>> lista = new ArrayList<HashMap<String,String>>();
		HashMap<String, String> mapa = new HashMap<String, String>();
		
		mapa.put(list2.get(1), list2.get(0));
		lista.add(mapa);
		
		return lista;
	}
}
